<template>
  <div class="menu-page">
    <el-card>
      <template #header>
        <div>菜单管理</div>
      </template>
      <div class="menu-tree-box">
        <el-tree
          :data="menuTreeData"
          :props="defaultProps"
          default-expand-all
          :expand-on-click-node="false"
        >
          <template #default="{ node, data }">
            <span class="custom-tree-node">
              <span>{{ node.label }}</span>
              <span>
                <a
                  :class="{
                    'disabled-link': ['1', '2'].includes(data.menuType),
                    'c-blue': !['1', '2'].includes(data.menuType)
                  }"
                  @click="addMenuFn(data)"
                >
                  新增
                </a>
                <a
                  :class="{
                    'disabled-link':
                      [0].includes(data.menuId) ||
                      ['2'].includes(data.menuType),
                    'c-black': !(
                      [0].includes(data.menuId) || ['2'].includes(data.menuType)
                    )
                  }"
                  :disabled="true"
                  @click="updateMenuFn(node, data)"
                  ml-8px
                  >编辑
                </a>
                <a
                  :class="{
                    'disabled-link': [0].includes(data.menuId),
                    'c-red': ![0].includes(data.menuId)
                  }"
                  ml-8px
                  @click="removeMenuFn(node, data)"
                >
                  删除
                </a>
              </span>
            </span>
          </template>
        </el-tree>
      </div>
    </el-card>
    <div class="menu-tree-form">
      <div class="btn-box">
        <el-button type="default" @click="resetForm"> 重置 </el-button>
        <el-button type="primary" @click="submitForm"> 提交 </el-button>
      </div>
      <div class="menu-form">
        <p class="m-8px">基础信息</p>
        <el-form
          ref="menuFormRef"
          :model="menuForm"
          label-width="80px"
          class="menu-form"
          inline
        >
          <el-form-item prop="menuName" label="菜单名称" w-300px>
            <el-input
              v-model="menuForm.menuName"
              placeholder="请输入菜单名称"
            ></el-input>
          </el-form-item>
          <el-form-item prop="parentId" label="上级菜单" w-300px>
            <el-tree-select
              v-model="menuForm.parentId"
              :data="menuTreeData"
              :props="defaultProps"
              default-expand-all
              placeholder="请选择上级菜单"
            >
            </el-tree-select>
          </el-form-item>
          <el-form-item prop="menuSort" label="菜单排序" w-300px>
            <el-input
              :disabled="formType === 0"
              v-model="menuForm.menuSort"
              type="number"
              placeholder="请输入菜单排序"
            ></el-input>
          </el-form-item>
          <el-form-item prop="icon" label="菜单图标" w-300px>
            <el-input
              v-model="menuForm.icon"
              placeholder="请输入菜单图标"
            ></el-input>
          </el-form-item>
          <el-form-item prop="menuType" label="菜单类型" w-300px>
            <el-select v-model="menuForm.menuType" placeholder="请选择菜单类型">
              <el-option label="目录" value="0"></el-option>
              <el-option label="菜单" value="1"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item
            prop="path"
            label="菜单地址"
            style="margin-right: 0; width: 100%"
          >
            <el-input
              v-model="menuForm.path"
              placeholder="请输入菜单地址"
            ></el-input>
          </el-form-item>
          <el-form-item
            prop="component"
            label="组件路径"
            style="margin-right: 0; width: 100%"
          >
            <el-input
              v-model="menuForm.component"
              placeholder="请输入组件路径"
            ></el-input>
          </el-form-item>
          <el-form-item
            prop="redirect"
            label="重定向"
            style="margin-right: 0; width: 100%"
            v-if="menuForm.menuType === '0'"
          >
            <el-input
              v-model="menuForm.redirect"
              placeholder="请输入重定向地址"
            ></el-input>
          </el-form-item>
        </el-form>
      </div>
      <div class="menu-action-table" v-if="menuForm.menuType === '1'">
        <p class="mt-8px mb-8px">菜单权限</p>
        <p class="mb-8px">
          <el-button type="primary" @click="handleAdd">
            <template #icon>
              <i-ep-plus />
            </template>
            新增
          </el-button>
        </p>
        <div class="table-box">
          <kt-table
            :tableData="tableData"
            :tableColumns="tableColumns"
            :showPagination="false"
          >
            <template #action="{ row }">
              <el-button
                type="primary"
                @click="handleEdit(row)"
                class="table-btn"
                link
              >
                <template #icon>
                  <i-ep-edit />
                </template>
                编辑
              </el-button>
              <el-button
                type="danger"
                @click="handleDelete(row)"
                class="table-btn"
                link
              >
                <template #icon>
                  <i-ep-delete />
                </template>
                删除
              </el-button>
            </template>
          </kt-table>
        </div>
      </div>
    </div>
    <el-dialog
      :title="authDialogTitle"
      v-model="authDialogVisible"
      width="50%"
      :before-close="closeAuthModal"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
    >
      <el-form
        inline
        ref="authMenuFormRef"
        :model="authMenuForm"
        :rules="authMenuFormRules"
        label-width="80px"
      >
        <el-form-item prop="menuName" label="权限名称" w-300px>
          <el-input
            v-model="authMenuForm.menuName"
            placeholder="请输入权限名称"
          ></el-input>
        </el-form-item>
        <el-form-item prop="path" label="权限地址" w-300px>
          <el-input
            v-model="authMenuForm.path"
            placeholder="请输入权限代码"
          ></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="closeAuthModal">取消</el-button>
        <el-button type="primary" @click="submitAuthForm">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { getMenuInfo, addMenu, updateMenu, deleteMenu } from "@/api/menu"
import { buildTree } from "@/utils/tools"
import { ElMessage } from "element-plus"

const menuTreeData = ref<any[]>([])
const selectMenu = ref<any>({})
const formType = ref<number>(0) // 0: 新增, 1: 编辑
const menuFormRef = ref()
const menuForm = ref({
  menuId: "",
  menuName: "",
  parentId: "",
  menuSort: "",
  icon: "",
  menuType: "0",
  path: "",
  component: "",
  redirect: ""
})
const tableData = ref<any[]>([])
const tableColumns = ref([
  {
    label: "功能名称",
    prop: "menuName"
  },
  {
    label: "功能代码",
    prop: "path"
  },
  {
    label: "操作",
    prop: "action",
    width: "200px",
    fixed: "right",
    slotName: "action"
  }
])
const authMenuFormRef = ref()
const authDialogVisible = ref(false)
const authDialogType = ref(0) // 0: 新增, 1: 编辑
const authDialogTitle = ref("")
const authMenuForm = ref({
  menuId: "",
  parentId: "",
  menuName: "",
  path: "",
  menuSort: ""
})
const authMenuFormRules = ref({
  menuName: [{ required: true, message: "请输入功能名称", trigger: "blur" }],
  path: [{ required: true, message: "请输入功能代码", trigger: "blur" }]
})
const defaultProps = {
  children: "children",
  label: "menuName"
}

// 处理树节点新增点击事件
const addMenuFn = async (data: any) => {
  clearForm()
  await nextTick()
  formType.value = 0
  selectMenu.value = data
  menuForm.value.parentId = data.menuId
  menuForm.value.menuSort = data.children.length
    ? data.children.reduce((a: any, b: any) => {
        return a.menuSort > b.menuSort ? a : b
      }).menuSort + 1
    : 1
}
// 处理树节点编辑事件
const updateMenuFn = async (node: any, data: any) => {
  clearForm()
  await nextTick()
  formType.value = 1
  selectMenu.value = data
  Object.keys(menuForm.value).forEach((key) => {
    ;(menuForm.value as Record<string, any>)[key] = data[key]
  })
  tableData.value = [...data.children]
}
// 处理树节点删除事件
const removeMenuFn = async (node: any, data: any) => {
  clearForm()
  await nextTick()
  deleteMenu({
    menuId: data.menuId
  })
    .then((res) => {
      if (res.code !== 0) {
        ElMessage.error(res.msg)
        return
      }
      ElMessage.success("删除成功")
      getMenuList()
    })
    .catch((err) => {
      console.log(err)
      ElMessage.error("删除失败")
    })
}
// 重置表单
const resetForm = () => {
  clearForm()
  if (formType.value === 0) {
    menuForm.value.parentId = selectMenu.value.menuId
  } else {
    Object.keys(menuForm.value).forEach((key) => {
      ;(menuForm.value as Record<string, any>)[key] = selectMenu.value[key]
    })
  }
}
// 提交表单
const submitForm = () => {
  menuFormRef.value.validate(async (valid: boolean) => {
    if (valid) {
      try {
        if (formType.value === 0) {
          const res = await addMenu({
            ...menuForm.value,
            subOperation: tableData.value
          })
          if (res.code !== 0) {
            ElMessage.error(res.msg)
            return
          }
          ElMessage.success("新增成功")
        } else {
          const res = await updateMenu({
            ...menuForm.value,
            subOperation: tableData.value,
            originSubOperation: selectMenu.value.children
          })
          if (res.code !== 0) {
            ElMessage.error(res.msg)
            return
          }
          ElMessage.success("更新成功")
        }
        // 提交成功后清空表单
        clearForm()
        getMenuList()
      } catch (error) {
        console.log(error)
        ElMessage.error("提交失败")
      }
    }
  })
}
// 清空表单
const clearForm = async () => {
  menuFormRef.value.resetFields()
  tableData.value = []
  await nextTick()
}
// 获取菜单列表
const getMenuList = async () => {
  const res = await getMenuInfo({})
  if (res.code !== 0) {
    ElMessage.error(res.msg)
    return
  }
  // 处理数据
  let menuList = res.data.rows
  menuList = menuList.map((item: any) => {
    item.value = item.menuId
    return item
  })
  const treeData = [
    {
      menuId: 0,
      value: 0,
      menuName: "菜单列表",
      children: buildTree(menuList, "menuId", "parentId")
    }
  ]
  menuTreeData.value = treeData
}
// 处理新增按钮点击事件
const handleAdd = () => {
  authDialogTitle.value = "新增权限"
  authDialogType.value = 0
  if (formType.value === 0) {
    authMenuForm.value.parentId = ""
  } else {
    authMenuForm.value.parentId = menuForm.value.menuId
  }
  authDialogVisible.value = true
}
// 处理编辑按钮点击事件
const handleEdit = (row: any) => {
  authDialogTitle.value = "编辑权限"
  authDialogType.value = 1
  Object.keys(authMenuForm.value).forEach((key) => {
    ;(authMenuForm.value as Record<string, any>)[key] = row[key]
  })
  authDialogVisible.value = true
}
// 处理删除按钮点击事件
const handleDelete = (row: any) => {
  const index = tableData.value.findIndex(
    (item: any) => item.menuSort === row.menuSort
  )
  if (index !== -1) {
    tableData.value.splice(index, 1)
  }
  ElMessage.success("删除成功")
}
// 关闭权限弹窗
const closeAuthModal = async () => {
  authMenuFormRef.value.resetFields()
  await nextTick()
  authDialogVisible.value = false
}
// 提交权限表单
const submitAuthForm = async () => {
  authMenuFormRef.value.validate(async (valid: boolean) => {
    if (valid) {
      const { menuName, path, menuId, parentId, menuSort } = authMenuForm.value
      if (authDialogType.value === 0) {
        // 校验path不可重复
        const index = tableData.value.findIndex(
          (item: any) => item.path === path
        )
        if (index !== -1) {
          ElMessage.error("功能代码不可重复")
          return
        }
        // 遍历tableData，menuSort为其中最大的值+1，为空则为1
        const maxMenuSort =
          tableData.value.reduce(
            (a: any, b: any) => {
              return a.menuSort > b.menuSort ? a : b
            },
            { menuSort: 0 }
          ).menuSort + 1
        tableData.value.push({
          menuName,
          path,
          menuId,
          parentId,
          menuSort: maxMenuSort,
          menuType: "2"
        })
        ElMessage.success("新增成功")
      } else {
        const index = tableData.value.findIndex(
          (item: any) => item.menuSort === menuSort
        )
        if (index !== -1) {
          tableData.value[index] = {
            ...tableData.value[index],
            menuType: "2",
            menuName,
            path,
            menuId,
            parentId,
            menuSort
          }
          ElMessage.success("编辑成功")
        } else {
          ElMessage.error("编辑失败")
          return
        }
      }
      // 提交成功后清空表单
      await nextTick()
      closeAuthModal()
    } else {
      return false
    }
  })
}

// 挂载生命周期
onMounted(() => {
  getMenuList()
})
</script>

<style lang="scss" scoped>
.menu-page {
  @apply h-100% flex;
  .menu-tree-box {
    @apply h-100% w-300px;
    .custom-tree-node {
      @apply flex-1 flex items-center justify-between pr-8px;
    }
  }
  .menu-tree-form {
    @apply flex-1;
    height: calc(100% - 32px);
    .btn-box {
      @apply flex items-right justify-end mb-16px;
      .el-button {
        margin-left: 8px;
      }
    }
    .menu-form {
    }
    .menu-action-table {
      @apply pr-8px pl-8px;
      border-top: 1px solid #e4e7ed;

      .table-box {
        @apply h-400px w-100%;
      }
    }
  }
}
</style>
